package com.shanghaionstar.remote.manager;

import android.Manifest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.text.Editable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

import com.onstar.cn.common.exception.OnStarException;
import com.onstar.cn.framework.annotation.FindViewById;
import com.onstar.cn.framework.mvp.base.IMVPView;
import com.onstar.cn.framework.mvp.base.core.BaseActivity;
import com.onstar.cn.framework.mvp.base.core.BaseFragment;
import com.onstar.cn.framework.utils.RxBus;
import com.onstar.cn.mag.enumtype.RemoteCommandsType;
import com.onstar.cn.weight.CustomButton;
import com.onstar.cn.weight.CustomImageView;
import com.onstar.cn.weight.DeleteEditText;
import com.shanghaionstar.R;
import com.shanghaionstar.pin.model.PinModel;
import com.shanghaionstar.pin.presenter.PinPresenter;
import com.shanghaionstar.utils.AlertDialogUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

import rx.Observable;
import rx.Subscriber;
import rx.functions.Action1;

import static android.support.v4.content.ContextCompat.checkSelfPermission;

/**
 * Created by 6335yz on 2016/2/3.
 */
public class PinDialogFragment extends DialogFragment implements View.OnClickListener, IMVPView {

    private CustomButton remote_dialog_cancel;
    private CustomButton remote_dialog_confirm;
    private CustomImageView remote_dialog_show_pwd;
    private DeleteEditText pin_edit;
    private String commandType;
    private int fromPage;
    private View remote_dialog_alarm_layout;
    private TextView remote_dialog_pwd_forget;
    private BaseActivity baseActivity;
    @FindViewById
    private CheckBox remote_dialog_alarm_flash, remote_dialog_alarm_honk;
    private PinPresenter pinPresenter;
    private ProgressDialog progDialog;
    private boolean isPinOK;
    private boolean isShowPwd = true;
    private CharSequence charSequence;

//    public interface OnPinCallBack {
//        void onPinSuccess();
//
//        void onPinFail();
//    }
//
//    private OnPinCallBack onPinCallBack;
//
//    public void registPinCallBack(OnPinCallBack onPinCallBack) {
//        this.onPinCallBack = onPinCallBack;
//    }


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.baseActivity = (BaseActivity) context;
    }

    @Override
    public void setLoading(boolean isLoading) {
        if (progDialog != null) {
            if (isLoading) {
                progDialog.show();
            } else {
                progDialog.dismiss();
            }
        }
    }

    @Override
    public void onResponseError(OnStarException e) {
        setLoading(false);
        AlertDialogUtil.showAlertDialog(baseActivity, getString(R.string.dialog_warning),
                e.getMessage());
        PinModel pinModel = getCurrentPinModel();
        pinModel.setPinSuccess(false);
//        onPinCallBack.onPinFail();
        RxBus.getDefault().post(fromPage, pinModel);
    }

    @Override
    public void onReponseSuccess(Object object) {
        setLoading(false);
        dismiss();
        if (object instanceof PinModel) {
            PinModel pinModel = getCurrentPinModel();
            pinModel.setPinSuccess(true);
            RxBus.getDefault().post(fromPage, pinModel);
//            onPinCallBack.onPinSuccess();
        }
    }

    @Override
    public Activity onActivity() {
        return null;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        pinPresenter = new PinPresenter(baseActivity.getScheduler(), baseActivity);
        pinPresenter.setView(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        View view = inflater.inflate(R.layout.pin_fragment_dialog, container);
        progDialog = new ProgressDialog(getActivity());
        progDialog.setMessage(getString(R.string.waiting));
        remote_dialog_alarm_layout = view.findViewById(R.id.remote_dialog_alarm_layout);

        remote_dialog_cancel = (CustomButton) view.findViewById(R.id.remote_dialog_cancel);
        remote_dialog_confirm = (CustomButton) view.findViewById(R.id.remote_dialog_confirm);
        remote_dialog_show_pwd = (CustomImageView) view.findViewById(R.id.remote_dialog_show_pwd);
        remote_dialog_alarm_flash = (CheckBox) view.findViewById(R.id.remote_dialog_alarm_flash);
        remote_dialog_alarm_honk = (CheckBox) view.findViewById(R.id.remote_dialog_alarm_honk);
        remote_dialog_pwd_forget = (TextView) view.findViewById(R.id.remote_dialog_pwd_forget);
        pin_edit = (DeleteEditText) view.findViewById(R.id.pin_edit);
        remote_dialog_cancel.setOnClickListener(this);
        remote_dialog_confirm.setOnClickListener(this);
        remote_dialog_show_pwd.setOnClickListener(this);
        commandType = getArguments().getString("commandType");
        fromPage = getArguments().getInt("fromPage");
        RemoteCommandsType remoteCommandsType = RemoteCommandsType.fromValue(commandType);
        if (remoteCommandsType == RemoteCommandsType.COMMANDS_ALERT) {
            remote_dialog_alarm_layout.setVisibility(View.VISIBLE);
        } else {
            remote_dialog_alarm_layout.setVisibility(View.GONE);
        }
        getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    dismiss();
                }
                return false;
            }
        });
        pin_edit.addTextChangedListener(new TextWatcher() {
            @Override
            public void afterTextChanged(Editable arg0) {
            }

            @Override
            public void beforeTextChanged(CharSequence str, int arg1, int arg2, int arg3) {
            }

            @Override
            public void onTextChanged(CharSequence str, int arg1, int arg2, int arg3) {
                pinRule(str);
            }
        });
        remote_dialog_alarm_honk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (!isChecked) {
                    if (!remote_dialog_alarm_flash.isChecked()) {
                        AlertDialogUtil.showAlertDialog(getActivity(), getActivity().getString(R.string.dialog_warning),
                                getActivity().getString(R.string.alert_not_null));
                        remote_dialog_alarm_honk.setChecked(true);
                    }
                }
            }
        });

        remote_dialog_alarm_flash.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (!isChecked) {
                    if (!remote_dialog_alarm_honk.isChecked()) {
                        AlertDialogUtil.showAlertDialog(getActivity(), getActivity().getString(R.string.dialog_warning),
                                getActivity().getString(R.string.alert_not_null));
                        remote_dialog_alarm_flash.setChecked(true);
                    }
                }
            }
        });
        String input = getString(R.string.remote_pwd_forget);
        final String phone = getContext().getString(R.string.connect_phone);
        StringBuilder sb = new StringBuilder();
        sb.append(input);
        sb.append(phone);
        String text = sb.toString();
        SpannableString ss = new SpannableString(sb.toString());
        ss.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                AlertDialogUtil.showAlertDialog(baseActivity, baseActivity.getString(R.string.dialog_warning), phone, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        baseActivity.requestRunTimePermissions(new String[]{Manifest.permission.CALL_PHONE}, new com.onstar.cn.framework.mvp.base.core.PermissionCall() {
                            @Override
                            public void requestSuccess() {
                                Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone));
                                baseActivity.startActivity(intent);
                            }

                            @Override
                            public void refused() {

                            }
                        });
                    }
                }, true);
                dismiss();
            }
        }, text.length() - phone.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new ForegroundColorSpan(getContext().getResources().getColor(R.color.color_0a4ba6)), text.length() - phone.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new UnderlineSpan(), text.length() - phone.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        remote_dialog_pwd_forget.setText(ss);
        remote_dialog_pwd_forget.setMovementMethod(LinkMovementMethod.getInstance());
        return view;
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            InputMethodManager imm = (InputMethodManager) getActivity()
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);
        }
    };

    @Override
    public void onResume() {
        super.onResume();
        pin_edit.setFocusable(true);
        pin_edit.setFocusableInTouchMode(true);
        pin_edit.requestFocus();
        Observable.create(new Observable.OnSubscribe<Object>() {
            @Override
            public void call(Subscriber<? super Object> subscriber) {

            }
        }).delay(400, TimeUnit.MILLISECONDS).subscribe(new Action1<Object>() {
            @Override
            public void call(Object o) {
                InputMethodManager imm = (InputMethodManager) baseActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
            }
        });
        handler.sendEmptyMessage(0);
        Window window = getDialog().getWindow();
        DisplayMetrics dm = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
        window.setLayout((int) (dm.widthPixels * 0.97), (int) (dm.heightPixels * 0.45));//Here!
        window.setGravity(Gravity.CENTER);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.remote_dialog_show_pwd:
                if (isShowPwd) {
                    pin_edit.isShowPassword(true);
                } else {
                    pin_edit.isShowPassword(false);
                }
                isShowPwd = !isShowPwd;
                break;
            case R.id.remote_dialog_cancel:
                dismiss();
                break;
            case R.id.remote_dialog_confirm:
                if (pinRule(pin_edit.getText())) {
                    PinModel pinModel = getCurrentPinModel();
                    pinModel.setPinSuccess(false);
                    pinPresenter.sendPin(pinModel);
                }
                break;
        }
    }

    private PinModel getCurrentPinModel() {
        PinModel pinModel = new PinModel();
        boolean isflash = true;
        boolean isHorn = true;
        if (remote_dialog_alarm_flash != null) {
            isflash = remote_dialog_alarm_flash.isChecked();
        }
        if (remote_dialog_alarm_honk != null) {
            isHorn = remote_dialog_alarm_honk.isChecked();
        }
        pinModel.setFlash(isflash);
        pinModel.setHorn(isHorn);
        pinModel.setPinCode(String.valueOf(pin_edit.getText()));
        pinModel.setRemoteCommandsType(RemoteCommandsType.fromValue(commandType));
        return pinModel;
    }

    /**
     * @param commandType
     * @param fromPage    从rxconstants.java中取
     * @return
     */
    public static PinDialogFragment newInstance(RemoteCommandsType commandType, int fromPage) {
        PinDialogFragment pinDialogFragment = new PinDialogFragment();
        Bundle bundle = new Bundle();
        bundle.putString("commandType", commandType.value());
        bundle.putInt("fromPage", fromPage);
        pinDialogFragment.setArguments(bundle);
        pinDialogFragment.setCancelable(false);
        return pinDialogFragment;
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        pinPresenter.finish();
    }

    private boolean pinRule(CharSequence str) {
        String expr = "[^0-9|^a-z|^A-Z]";
        Pattern pattern = Pattern.compile(expr);
        String[] strs = pattern.split(str.toString());
        if (strs.length == 0) {
            AlertDialogUtil.showAlertDialog(baseActivity, 0, R.string.pin_format_error);
            pin_edit.setText("");
            return false;
        } else if (strs[0].equals(str.toString())) {
        } else {
            pin_edit.setText(strs[0]);
            pin_edit.setSelection(strs[0].length());
            AlertDialogUtil.showAlertDialog(baseActivity, 0, R.string.pin_format_error);
            return false;
        }
        return true;
    }

    private final int permissionRequestCode = 110;
    private BaseFragment.PermissionCall mPermissionCall;
   /* 处理权限问题*/

    /**
     * 对子类提供的申请权限方法
     *
     * @param permissions 申请的权限
     */
    public void requestRunTimePermissions(String[] permissions, BaseFragment.PermissionCall call) {
        if (permissions == null || permissions.length == 0)
            return;
        mPermissionCall = call;
        if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M) || checkPermissionGranted(permissions)) {
            //提示已经拥有权限
            mPermissionCall.requestSuccess();
        } else {
            //申请权限
            requestPermission(findDeniedPermissions(permissions), permissionRequestCode);
        }
    }

    public boolean checkPermissionGranted(String... permissions) {
        boolean result = true;
        for (String p : permissions) {
            if (checkSelfPermission(getActivity(), p) != PackageManager.PERMISSION_GRANTED) {
                result = false;
                break;
            }
        }
        return result;
    }

    private boolean shouldShowRequestPermissionRationale(String[] permissions) {
        boolean flag = false;
        for (String p : permissions) {
            if (shouldShowRequestPermissionRationale(p)) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    private void requestPermission(final String[] permissions, final int requestCode) {
        try {
//            if (shouldShowRequestPermissionRationale(permissions)) {
//                new AlertDialog.Builder(getActivity())
//                        .setTitle(R.string.attention)
//                        .setMessage(R.string.content_to_request_permission)
//                        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
//                            @Override
//                            public void onClick(DialogInterface dialog, int which) {
//                                requestPermissions(permissions, requestCode);
//                            }
//                        }).show();
//            } else {
//                requestPermissions( permissions, permissionRequestCode);
//            }
            requestPermissions(permissions, permissionRequestCode);

        } catch (Exception e) {
            Log.e("", e.getMessage());
        }

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == permissionRequestCode) {
            if (verifyPermissions(grantResults)) {
                mPermissionCall.requestSuccess();
                mPermissionCall = null;
            } else {
                mPermissionCall.refused();
                mPermissionCall = null;
            }
        }
    }

    public boolean verifyPermissions(int[] grantResults) {
        // At least one result must be checked.
        if (grantResults.length < 1) {
            return false;
        }

        // Verify that each required permission has been granted, otherwise return false.
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    public interface PermissionCall {
        //申请成功
        void requestSuccess();

        //拒绝
        void refused();
    }

    public String[] findDeniedPermissions(String... permission) {
        List<String> denyPermissions = new ArrayList<>();
        for (String value : permission) {
            if (checkSelfPermission(getActivity(), value) != PackageManager.PERMISSION_GRANTED) {
                denyPermissions.add(value);
            }
        }
        return denyPermissions.toArray(new String[denyPermissions.size()]);
    }
}
